﻿package glam.skins;
import flash.display.BitmapData;
import flash.display.InteractiveObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import fpc.controls.ButtonIcon;
import fpc.styles.skins.ButtonState;
import fpc.styles.skins.IScaledButtonSkin;
import fpc.utils.IFactory;
import fpc.utils.Maths;
import fpc.utils.ScaledBitmap;
import glam.Primitives;

class GlamScaledButton implements IFactory<IScaledButtonSkin>
{
	var _shape:BitmapData;
	
	var _disabledShape:BitmapData;
	
	var _topColor:UInt;
	
	var _topAlpha:Float;
	
	var _textColor:UInt;
	
	var _textColorDisabled:UInt;
	
	public function new(primitives:Primitives = null) 
	{
		if (primitives == null)
		{
			primitives = Primitives.defaultPrimitives;
		}
		_shape = primitives.getButtonBackground();
		_disabledShape = primitives.getButtonBackgroundDisabled();
		_topColor = primitives.buttonBackgroundTopColor;
		_topAlpha = primitives.buttonBackgroundTopAlpha;
		_textColor = primitives.textColor;
		_textColorDisabled = primitives.textColorDisabled;
	}
	
	public function create():IScaledButtonSkin
	{
		return new GlamScaledButtonSkin(_shape, _disabledShape, _topColor, _topAlpha, _textColor, _textColorDisabled);
	}
}

class GlamScaledButtonSkin implements IScaledButtonSkin
{
	public var object(default, null):InteractiveObject;
	
	var _sprite:Sprite;
	
	var _tf:TextField;
	
	var _scaled:ScaledBitmap;
	
	var _topShape:Shape;
	
	var _shape:BitmapData;
	
	var _disabledShape:BitmapData;
	
	var _textColor:UInt;
	
	var _textColorDisabled:UInt;
	
	public function new(
		shape:BitmapData, disabledShape:BitmapData, topColor:UInt, topAlpha:Float, textColor:UInt, textColorDisabled:UInt
	)
	{
		_shape = shape;
		_disabledShape = disabledShape;
		
		_sprite = new Sprite();
		object = _sprite;
		
		_scaled = new ScaledBitmap(_sprite.graphics, shape);
		
		_topShape = new Shape();
		var g = _topShape.graphics;
		g.beginFill(topColor, topAlpha);
		g.drawRoundRect(0, 0, 20, 20, 6);
		g.endFill();
		_topShape.scale9Grid = new Rectangle(5, 5, 10, 10);
		_sprite.addChild(_topShape);
		
		_textColor = textColor;
		_textColorDisabled = textColorDisabled;
		
		_tf = new TextField();
		_tf.autoSize = TextFieldAutoSize.LEFT;
		_tf.selectable = false;
		_tf.defaultTextFormat = new TextFormat('Tahoma', 12, textColor);
		_sprite.addChild(_tf);
		
		_enabled = true;
		_over = false;
		_down = false;
		_topAnimation = 0;
		_isOn = true;
		updateTopAnimation();
	}
	
	public var text:String;
	
	public var icon:ButtonIcon;
	
	public function calculateMinSize()
	{
		minWidth = Std.int(_tf.width) + 4;
		minHeight = Std.int(_tf.height) + 4;
	}
	
	//TODO вынести эту функцию
	public function resize()
	{	
		var cTop = _topShape;
		if (_down)
		{
			_scaled.setBounds(0, 0, width, height);
		}
		else
		{
			_scaled.setBounds( -1, -1, width + 2, height + 2);
		}
		
		updateTopAnimation();
	}
	
	public var minWidth(default, null):Int;
	
	public var minHeight(default, null):Int;
	
	public var height:Int;
	
	public var width:Int;
	
	public var state:ButtonState;
	
	public var selected:Bool;
	
	var _needResize:Bool;
	
	public function update()
	{
		_needResize = true;
		
		_tf.text = text;
		_tf.x = Maths.center(width, _tf.width);
		_tf.y = Maths.center(height, _tf.height);
		
		switch (state)
		{
			case NORMAL:
				setOver(false);
				setDown(false);
				setEnabled(true);
			case OVER:
				setOver(true);
				setDown(false);
				setEnabled(true);
			case DOWN:
				setDown(true);
				setOver(true);
				setEnabled(true);
			case DISABLED:
				setEnabled(false);
				setDown(false);
				setOver(false);
		}
		
		if (_needResize)
		{
			resize();
		}
	}
	
	static var ANIMATION_STEP = .2;
	
	var _over:Bool;
	
	var _isOn:Bool;
	
	function setOver(value:Bool)
	{
		if (value == _over)
		{
			return;
		}
		
		_over = value;
		
		if (value)
		{
			if (_topAnimation < 0)
			{
				_topAnimation = 0;
			}
			_isOn = true;
			_sprite.addEventListener(Event.ENTER_FRAME, onOverEnterFrame);
		}
		else
		{
			if (_topAnimation > 1)
			{
				_topAnimation = 1;
			}
			_isOn = false;
			_sprite.addEventListener(Event.ENTER_FRAME, onOverEnterFrame);
		}
	}
	
	function onOverEnterFrame(event:Event)
	{
		if ((_topAnimation += _isOn ? ANIMATION_STEP : -ANIMATION_STEP) > 1)
		{
			_topAnimation = 1;
			_sprite.removeEventListener(Event.ENTER_FRAME, onOverEnterFrame);
		}
		else if (_topAnimation < 0)
		{
			_topAnimation = 0;
			_sprite.removeEventListener(Event.ENTER_FRAME, onOverEnterFrame);
		}
		updateTopAnimation();
	}
	
	var _topAnimation:Float;
	
	function updateTopAnimation()
	{
		var top = _topShape;
		if (selected && _topAnimation < .5)
		{
			_topAnimation = .5;
		}
		if (_topAnimation <= .00001)
		{
			top.visible = false;
		}
		else
		{			
			if (!top.visible)
			{
				top.visible = true;
			}
			var k = .5 + Math.sqrt(_topAnimation) / 2;
			
			top.alpha = _isOn
				? (selected ? 1 : .8)
				: (selected ? 1.2 : .8) * k * 1.2 - .5;
			var border = _down ? 4 : 2;
			top.width = (width - border) * k - 2;
			top.height = (height - border) * k - 2;
			top.x = (width - top.width) / 2;
			top.y = (height - top.height) / 2;
		}
	}
	
	var _down:Bool;
	
	function setDown(value:Bool)
	{
		if (value == _down)
		{
			return;
		}
		
		_down = value;
		
		_needResize = true;
	}
	
	var _enabled:Bool;
	
	function setEnabled(value:Bool)
	{
		if (value == _enabled)
		{
			return;
		}
		
		_enabled = value;
		
		_tf.textColor = value ? _textColor : _textColorDisabled;
		_scaled.bitmapData = value ? _shape : _disabledShape;
	}
}
